/******************************************************************************
* echo_client.c                                                               *
*                                                                             *
* Description: This file contains the C source code for an echo client.  The  *
*              client connects to an arbitrary <host,port> and sends input    *
*              from stdin.                                                    *
*                                                                             *
* Authors: Athula Balachandran <abalacha@cs.cmu.edu>,                         *
*          Wolf Richter <wolf@cs.cmu.edu>                                     *
*                                                                             *
*******************************************************************************/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <fcntl.h>

#define ECHO_PORT 9999
#define BUF_SIZE 4096

int main(int argc, char* argv[])
{
    if (argc != 4)
    {
        fprintf(stderr, "usage: %s <server-ip> <port>",argv[0]);
        return EXIT_FAILURE;
    }

    char buf[BUF_SIZE];
        
    int status, sock;
    struct addrinfo hints;
	memset(&hints, 0, sizeof(struct addrinfo));
    struct addrinfo *servinfo; //will point to the results
    hints.ai_family = AF_INET;  //IPv4
    hints.ai_socktype = SOCK_STREAM; //TCP stream sockets
    hints.ai_flags = AI_PASSIVE; //fill in my IP for me

    if ((status = getaddrinfo(argv[1], argv[2], &hints, &servinfo)) != 0) 
    {
        fprintf(stderr, "getaddrinfo error: %s \n", gai_strerror(status));
        return EXIT_FAILURE;
    }

    if((sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1)
    {
        fprintf(stderr, "Socket failed");
        return EXIT_FAILURE;
    }
    
    if (connect (sock, servinfo->ai_addr, servinfo->ai_addrlen) == -1)
    {
        fprintf(stderr, "Connect不上");
        return EXIT_FAILURE;
    }
        
    // char msg[BUF_SIZE]; 
    // fgets(msg, BUF_SIZE, stdin);
    FILE *file = fopen(argv[3], "rb"); // 以二进制模式读取
    if (!file) {
        fprintf(stderr, "Failed to open file: %s\n", argv[3]);
        freeaddrinfo(servinfo);
        close(sock);
        return EXIT_FAILURE;
    }
    
    //读取文件
    size_t bytes_read = fread(buf, 1, BUF_SIZE, file);
    if (bytes_read == 0) {
        fprintf(stderr, "File is empty or read error\n");
        fclose(file);
        freeaddrinfo(servinfo);
        close(sock);
        return EXIT_FAILURE;
    }

    //打印内容
    fprintf(stdout, "Sending ");
    fwrite(buf, 1, bytes_read, stdout);  // 输出原始内容
    fprintf(stdout, "\n");
    

    // send(sock, msg , strlen(msg), 0);
    //向服务器发送数据
    if (send(sock, buf, bytes_read, 0) != bytes_read) {
        fprintf(stderr, "Failed to send full data\n");
    }

    //从服务器接收数据
    
    int cnt=0;
    int bytes_total=0;
    // if((bytes_received = recv(sock, buf, BUF_SIZE, 0)) > 1)
    // {
    //     buf[bytes_received] = '\0';
        
    // }        
    //在客户端也要改成循环接收
    while(1){
        //循环接收
        int bytes_received;
        bytes_received = recv(sock, buf + bytes_total, BUF_SIZE - bytes_total, 0);
        cnt++;//表示接收的第几轮数据
        fprintf(stdout,"%d\n",cnt);
        if(bytes_received>0){
            buf[bytes_received] = '\0';
            
            if(cnt==1){
                //最开始接收打印提示信息
                fprintf(stdout, "========Received========\r\n");
            }
            fprintf(stdout,"%s",buf);
            continue;
            //memset(buf, 0, BUF_SIZE);
        }
        else if(bytes_received==0){
            fprintf(stdout,"\nConnection closed!\n");
            break;
        }
        else{
            fprintf(stdout,"\nWrs error!");
            break;
        }
        
    }

    freeaddrinfo(servinfo);
    close(sock);    
    return EXIT_SUCCESS;
}

